/*
# File    :   fsm.h
# Author  :   schips, toujizhe
# Git     :   https://gitee.com/schips/
# Ref     :   https://www.cnblogs.com/toujizhe/articles/5473489.html
# Date    :   2016-05-09 12:20, 2019-05-27 
# Describe:     
              一个可以复位到状态机，根据ref的源码进行改善
              这个版本的状态机只提供 框架，具体的实现由开发者自行完成
*/
#ifndef __FSM_H_
#define __FSM_H_
/* ----------------------- Defines ------------------------------------------*/
// 数据类型定义区
typedef unsigned char State;
typedef State(*Procedure)(void *);
typedef struct _SM_STATE {
    State cs;       // 当前状态
    State ns;       // 下个状态
} SM_STATE;

typedef struct _SM_VALUE {
    // 自定义数据结构
    int cnt;
} SM_VALUE;

// 状态机参数
typedef struct _SM_VAR {
    // 现在的状态以及下个状态
    SM_STATE st;

    // 状态机跳转表
    Procedure *Steps;

    // 状态机数据区域
    void * var;
} SM_ARG;


// 配置状态机的跳转表
static inline void config_sm_entry(void* arg, Procedure *sm_fun);

// 配置状态机的数据域
static inline void config_data_entry(void* arg, void *data);

// 驱动状态机
static inline int run_state_machine_once(void *arg);

/* ----------------------- Start implementation -----------------------------*/

static inline void config_sm_entry(void* arg, Procedure *sm_fun)
{
    SM_ARG *p = (SM_ARG *)arg;
    p->Steps = sm_fun;
}

static inline void config_data_entry(void* arg, void *data)
{
    SM_ARG *p = (SM_ARG *)arg;
    p->var = data;
}


static inline void set_state(void *arg, State st)
{
    SM_ARG *p = (SM_ARG *)arg;
    p->st.ns = st;
}

static inline int run_state_machine_once(void *arg)
{
    SM_ARG *p = (SM_ARG *)arg;

    // 记录当前状态
    p->st.cs = p->st.ns;

    // 根据现在情况 跳转到下一个状态
    // (需要具体实现中返回下一次的状态)
    p->st.ns = p->Steps[p->st.cs](arg);
    
    // 返回当前状态（可根据需要修改）
    return p->st.cs;
}

#endif /* __FSM_H_ */
